package com.qing.seckill.service.impl;

import com.alibaba.fastjson.JSON;
import com.qing.seckill.entity.OrderRecord;
import com.qing.seckill.entity.TbSeckillGoods;
import com.qing.seckill.entity.TbSeckillOrder;
import com.qing.seckill.mapper.TbSeckillGoodsMapper;
import com.qing.seckill.mapper.TbSeckillOrderMapper;
import com.qing.seckill.result.Result;
import com.qing.seckill.scheduled.SysContant;
import com.qing.seckill.service.ITbSeckillOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qing.seckill.service.thread.CreateOrderThread;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zhipeng.cao
 * @since 2021-04-19
 */
@Service
public class TbSeckillOrderServiceImpl extends ServiceImpl<TbSeckillOrderMapper, TbSeckillOrder> implements ITbSeckillOrderService {
	@Autowired
	private StringRedisTemplate redisTemplate;

	@Autowired
	private TbSeckillGoodsMapper goodsMapper;

	@Autowired
	private ThreadPoolTaskExecutor executor;

	@Autowired
	private CreateOrderThread createOrderThread;


	@Override
	public Result serveOrder(Long id) {
		String userId = "zhipeng.cao";
		/*//1.从Redis获取商品
		TbSeckillGoods seckillGoods= (TbSeckillGoods) redisTemplate.boundHashOps(TbSeckillGoods.class.getSimpleName()).get(id);
		//2. 判断商品是否存在，以及是否售罄
		if(null==seckillGoods||seckillGoods.getStockCount()<=0){
			return  Result.fail("商品已售罄，请查看其他商品！");  //商品已售完
		}*/
		//TOOD 优化
		String goodsId = redisTemplate.boundListOps(SysContant.SECKILL_PREFIX + id).rightPop();
		if (StringUtils.isEmpty(goodsId)) {
			return Result.fail("商品已售罄，请查看其他商品！");  //商品已售完
		}
		String jsonStr = (String) redisTemplate.boundHashOps(TbSeckillGoods.class.getSimpleName()).get(goodsId);
		TbSeckillGoods seckillGoods = JSON.parseObject(jsonStr, TbSeckillGoods.class);
		//3. 创建秒杀订单
		TbSeckillOrder seckillOrder = new TbSeckillOrder();
		seckillOrder.setCreateTime(LocalDateTime.now());
		seckillOrder.setMoney(seckillGoods.getCostPrice());
		seckillOrder.setSeckillId(System.currentTimeMillis());
		seckillOrder.setSellerId(seckillGoods.getSellerId());
		seckillOrder.setUserId(userId);
		//4。 秒杀订单存入缓存，库存-1
		redisTemplate.boundHashOps(TbSeckillOrder.class.getSimpleName()).put(userId, JSON.toJSONString(seckillOrder));
		seckillGoods.setStockCount(seckillGoods.getStockCount() - 1);
		//5. 判断库存是否<=0
		if (seckillGoods.getStockCount() <= 0) {
			//是，更新秒杀商品，保存秒杀订单，删除缓存
			goodsMapper.updateById(seckillGoods);
			redisTemplate.boundHashOps(TbSeckillGoods.class.getSimpleName()).delete(goodsId);
		} else {
			//否，更新商品缓存
			redisTemplate.boundHashOps(TbSeckillGoods.class.getSimpleName()).put(goodsId, JSON.toJSONString(seckillGoods));
		}
		return Result.success("秒杀成功，请你尽快支付！");  //秒杀成功尽快支付
	}


	@Override
	public Result serveOrder(Long id, String userId) {
		//1、判断用户是否在排队队列
		Boolean isMember = redisTemplate.boundSetOps(SysContant.SECKILL_USRE + id).isMember(userId);
		if (isMember) {
			TbSeckillOrder seckillOrder = JSON.parseObject((String) redisTemplate.boundHashOps(TbSeckillOrder.class.getSimpleName()).get(userId), TbSeckillOrder.class);
			// 	1.1在排队，判断用户是否在订单队列中
			if (Objects.nonNull(seckillOrder)) {
				//	1.1.1在订单队列中，你已经抢购成功，请尽快支付订单
				return Result.success("你已经抢购成功，请尽快支付");
			} else {
				//  1.1.2 不在订单队列，你正在排队，请耐心等待。。
				return Result.success("你在排队，请耐心等候。。");
			}
		}


		//2. 判断商品是否售罄
		String goodsId = redisTemplate.boundListOps(SysContant.SECKILL_PREFIX + id).rightPop();
		if (StringUtils.isEmpty(goodsId)) {
			return Result.fail("对不起商品已经售罄，请查看其它商品！");
		}
		redisTemplate.boundSetOps(SysContant.SECKILL_USRE + id).add(userId);
		redisTemplate.boundListOps(OrderRecord.class.getSimpleName()).leftPush(JSON.toJSONString(new OrderRecord(userId, id)));
		executor.execute(createOrderThread);
		return Result.success("你已经抢购成功，请尽快支付");
	}
}
